package ca.etsmtl.log121.tp3.swing;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;

import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;

import ca.etsmtl.log121.tp3.file.FileManager;
import ca.etsmtl.log121.tp3.model.PerspectiveModel;
import ca.etsmtl.log121.tp3.view.PerspectiveView;

public class MenuManager {
	private ApplicationFrame application;

	private JMenu markersMenu;

	private JMenuItem openFileItem, closeFileItem;

	private JMenuItem undoEditItem, redoEditItem, copyPerspectiveItem, pastePerspectiveItem, zoominEditItem, zoomoutEditItem, normalEditItem, moveupEditItem, moveleftEditItem, moverightEditItem, movedownEditItem;

	private JMenuItem newPerspectiveItem, renamePerspectiveItem, closePerspectiveItem, nextPerspectiveItem, previousPerspectiveItem;

	private JMenuItem newMarkersItem;

	public MenuManager(ApplicationFrame application) {
		this.application = application;

		buildMenu();
		refresh();
	}

	private void buildMenu() {
		openFileItem = new JMenuItem("Open Image");
		openFileItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK));
		openFileItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				File file = FileManager.fileChooserDialog(application.getMainPanel());

				if (file != null) {
					try {
						BufferedInputStream input = FileManager.openImage(file);

						if (input != null) {
							application.getController().openImage(input);
						}

//						input.close();
					} catch (IOException e1) { // FIXME: Handle this
						e1.printStackTrace();
					} catch (Exception e1) { // Other exception here (null)
						e1.printStackTrace();
					}
				}
			}
		});

		closeFileItem = new JMenuItem("Close Image");
		closeFileItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.CTRL_MASK | InputEvent.SHIFT_MASK));
		closeFileItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				application.getController().closeImage();
			}
		});

		JMenuItem quitFileItem = new JMenuItem("Quit");
		quitFileItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, InputEvent.CTRL_MASK));
		quitFileItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});

		JMenu fileMenu = new JMenu("File");
		fileMenu.add(openFileItem);
		fileMenu.add(closeFileItem);
		fileMenu.addSeparator();
		fileMenu.add(quitFileItem);

		undoEditItem = new JMenuItem("Undo");
		undoEditItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.CTRL_MASK));
		undoEditItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				application.getController().undo();
			}
		});

		redoEditItem = new JMenuItem("Redo");
		redoEditItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.CTRL_MASK | InputEvent.SHIFT_MASK));
		redoEditItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				application.getController().redo();
			}
		});

		zoominEditItem = new JMenuItem("Zoom In");
		zoominEditItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, InputEvent.CTRL_MASK));
		zoominEditItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) { // FIXME: Use command here
				PerspectiveView view = application.getController().getCurrentPerspectiveView();
				PerspectiveModel perspective = view.getPerspective();

//				perspective.modifyZoomFactor(1);
				perspective.setZoomFactor(perspective.getZoomFactor()+1*PerspectiveModel.ZOOMFACTOR_MULTIPLIER);
				view.repaint(); // FIXME: Use the patter observer to notify the view
			}
		});

		zoomoutEditItem = new JMenuItem("Zoom Out");
		zoomoutEditItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, InputEvent.CTRL_MASK));
		zoomoutEditItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) { // FIXME: Use command here
				PerspectiveView view = application.getController().getCurrentPerspectiveView();
				PerspectiveModel perspective = view.getPerspective();

//				perspective.modifyZoomFactor(-1);
				perspective.setZoomFactor(perspective.getZoomFactor()-1*PerspectiveModel.ZOOMFACTOR_MULTIPLIER);
				view.repaint(); // FIXME: Use the patter observer to notify the view
			}
		});

		normalEditItem = new JMenuItem("Normal Size");
		normalEditItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_0, InputEvent.CTRL_MASK));
		normalEditItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) { // FIXME: Use command here
				PerspectiveView view = application.getController().getCurrentPerspectiveView();
				PerspectiveModel perspective = view.getPerspective();

				perspective.setZoomFactor(PerspectiveModel.ZOOMFACTOR_MULTIPLIER);
				view.repaint(); // FIXME: Use the patter observer to notify the view
			}
		});

		moveupEditItem = new JMenuItem("Move Up");
		moveupEditItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.CTRL_MASK));
		moveupEditItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO
			}
		});

		moveleftEditItem = new JMenuItem("Move Left");
		moveleftEditItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, InputEvent.CTRL_MASK));
		moveleftEditItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO
			}
		});

		moverightEditItem = new JMenuItem("Move Right");
		moverightEditItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, InputEvent.CTRL_MASK));
		moverightEditItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO
			}
		});

		movedownEditItem = new JMenuItem("Move Down");
		movedownEditItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.CTRL_MASK));
		movedownEditItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO
			}
		});

		JMenu editMenu = new JMenu("Edit");
		editMenu.add(undoEditItem);
		editMenu.add(redoEditItem);
//		editMenu.addSeparator();
//		editMenu.add(zoominEditItem);
//		editMenu.add(zoomoutEditItem);
//		editMenu.add(normalEditItem);
//		editMenu.addSeparator();
//		editMenu.add(moveupEditItem);
//		editMenu.add(moveleftEditItem);
//		editMenu.add(moverightEditItem);
//		editMenu.add(movedownEditItem);

		newPerspectiveItem = new JMenuItem("New Perspective");
		newPerspectiveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.CTRL_MASK));
		newPerspectiveItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				application.getController().newPerspective();
			}
		});

		renamePerspectiveItem = new JMenuItem("Rename current Perspective");
		renamePerspectiveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, InputEvent.CTRL_MASK));
		renamePerspectiveItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				application.getController().renamePerspective();
			}
		});

		closePerspectiveItem = new JMenuItem("Close current Perspective");
		closePerspectiveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.CTRL_MASK));
		closePerspectiveItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				application.getController().removePerspective();
			}
		});

		copyPerspectiveItem = new JMenuItem("Copy Perspective");
		copyPerspectiveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK));
		copyPerspectiveItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO
			}
		});

		pastePerspectiveItem = new JMenuItem("Paste Perspective");
		pastePerspectiveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK));
		pastePerspectiveItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO
			}
		});

		nextPerspectiveItem = new JMenuItem("Next Perspective");
		nextPerspectiveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.CTRL_MASK));
		nextPerspectiveItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				application.getTabbedPane().setSelectedIndex(application.getTabbedPane().getNextTab());
			}
		});

		previousPerspectiveItem = new JMenuItem("Previous Perspective");
		previousPerspectiveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.CTRL_MASK | InputEvent.SHIFT_MASK));
		previousPerspectiveItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				application.getTabbedPane().setSelectedIndex(application.getTabbedPane().getPreviousTab());
			}
		});

		JMenu perspectivesMenu = new JMenu("Perspectives");
		perspectivesMenu.add(newPerspectiveItem);
		perspectivesMenu.add(renamePerspectiveItem);
		perspectivesMenu.add(closePerspectiveItem);
		perspectivesMenu.addSeparator();
		perspectivesMenu.add(copyPerspectiveItem);
		perspectivesMenu.add(pastePerspectiveItem);
		perspectivesMenu.addSeparator();
		perspectivesMenu.add(nextPerspectiveItem);
		perspectivesMenu.add(previousPerspectiveItem);

		newMarkersItem = new JMenuItem("New Marker");
		newMarkersItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_MASK));
		newMarkersItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				application.getController().newMarker();
			}
		});

		markersMenu = new JMenu("Markers");

//		rebuildMarkersMenu();

		JMenuItem aboutItem = new JMenuItem("About");
		aboutItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				JOptionPane.showMessageDialog(application.getMainPanel(), ApplicationFrame.APPLICATION_NAME + " Version 1.0", "About " + ApplicationFrame.APPLICATION_NAME, JOptionPane.INFORMATION_MESSAGE); // FIXME
			}
		});

		JMenu toolsMenu = new JMenu("Tools");
		toolsMenu.add(aboutItem);

		JMenuBar menuBar = new JMenuBar();
		menuBar.add(fileMenu);
		menuBar.add(editMenu);
		menuBar.add(perspectivesMenu);
		menuBar.add(markersMenu);
		menuBar.add(toolsMenu);

		application.setJMenuBar(menuBar);
	}

	public void rebuildMarkersMenu() {
		markersMenu.removeAll();

		markersMenu.add(newMarkersItem);
		markersMenu.addSeparator();
	}

	public void addMarker(JMenuItem item) {
		markersMenu.add(item);
	}

	public void refresh() {
		boolean bool = application.getController().isImageOpened();

		openFileItem.setEnabled(!bool);
		closeFileItem.setEnabled(bool);

		undoEditItem.setEnabled(bool);
		redoEditItem.setEnabled(bool);
		zoominEditItem.setEnabled(bool);
		zoomoutEditItem.setEnabled(bool);
		normalEditItem.setEnabled(bool);
		moveupEditItem.setEnabled(bool);
		moveleftEditItem.setEnabled(bool);
		moverightEditItem.setEnabled(bool);
		movedownEditItem.setEnabled(bool);

		newPerspectiveItem.setEnabled(bool);
		renamePerspectiveItem.setEnabled(bool);
		closePerspectiveItem.setEnabled(bool);
		copyPerspectiveItem.setEnabled(bool);
		pastePerspectiveItem.setEnabled(bool);
		nextPerspectiveItem.setEnabled(bool);
		previousPerspectiveItem.setEnabled(bool);

		newMarkersItem.setEnabled(bool);
	}
}
